package indi.henry.demo.service.impl;

import java.security.MessageDigest;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import indi.henry.demo.constant.Constants;
import indi.henry.demo.exception.BadRequestException;
import indi.henry.demo.service.ShortenService;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class ShortenServiceImpl implements ShortenService {

    @Value("${app.salt}")
    private String salt;

    @Override
    public String convertUrl(String url) {
        url = url.contains("//") ? url : "//" + url;
        return url.toLowerCase();
    }

    @Override
    public String shortUrl(String url) {

        String hex = Optional.ofNullable(md5ByHex(salt + url)).orElseThrow(() -> new BadRequestException("Invalid URL"));

        char[] resUrl = new char[4];
        for (int i = 0; i < 4; i++) {

            String sTempSubString = hex.substring(i * 8, i * 8 + 8);

            long lHexLong = 0x3FFFFFFF & Long.parseLong(sTempSubString, 16);
            long index = 0x0000003D & lHexLong;

            resUrl[i] = Constants.CHARS[(int) index];
        }
        return new String(resUrl);
    }

    private String md5ByHex(String src) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] b = src.getBytes();
            md.reset();
            md.update(b);
            byte[] hash = md.digest();
            String hs = "";
            String stmp = "";
            for (int i = 0; i < hash.length; i++) {
                stmp = Integer.toHexString(hash[i] & 0xFF);
                if (stmp.length() == 1)
                    hs = hs + "0" + stmp;
                else {
                    hs = hs + stmp;
                }
            }
            return hs.toUpperCase();
        } catch (Exception e) {
            log.error("Error Message: {}", e.getMessage());
            return null;
        }
    }
}
